import { constantRoutes } from '@/router'
import Layout from '@/layout'
const _import = require('../../router/_import_' + process.env.NODE_ENV + '.js') // 获取组件的方法

/**
 * 使用 meta.role 确定当前用户是否具有权限
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * 通过递归异步过滤路由表
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.component) {
        if (tmp.component === 'Layout') {
          tmp.component = Layout
        } else {
          try {
            tmp.component = _import(tmp.component) // 导入组件
          } catch (e) {
            console.log(e)
            const error = 'Error: Cannot find module \'' + tmp.component + '\'.vue'
            throw error
          }
        }
      }
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

/**
 * 生成扁平化机构路由(仅两级结构)
 * @param { 允许访问的路由Tree } accessRoutes
 * 路由基本机构:
 * {
 *   name: String,
 *   path: String,
 *   component: Component,
 *   redirect: String,
 *   children: [
 *   ]
 * }
 */
function generateFlatRoutes(accessRoutes) {
  const flatRoutes = []
  for (const item of accessRoutes) {
    let childrenFlatRoutes = []
    if (item.children && item.children.length > 0) {
      childrenFlatRoutes = castToFlatRoute(item.children, '')
    }
    // 处理二级路由
    flatRoutes.push({
      name: item.name,
      path: item.path,
      component: item.component,
      redirect: item.redirect,
      children: childrenFlatRoutes
    })
  }
  return flatRoutes
}

/**
 * 将子路由转换为扁平化路由数组（仅一级）
 * @param {待转换的子路由数组} routes
 * @param {父级路由路径} parentPath
*/

function castToFlatRoute(routes, parentPath, flatRoutes = []) {
  for (const item of routes) {
    if (item.children && item.children.length > 0) {
      if (item.redirect && item.redirect !== '') {
        flatRoutes.push({
          name: item.name,
          path: (parentPath + '/' + item.path).substring(1),
          redirect: item.redirect,
          meta: item.meta
        })
      }
      castToFlatRoute(item.children, parentPath + '/' + item.path, flatRoutes)
    } else {
      flatRoutes.push({
        name: item.name,
        path: (parentPath + '/' + item.path).substring(1),
        component: item.component,
        meta: item.meta
      })
    }
  }
  return flatRoutes
}

const actions = {
  generateRoutes({ commit }, userInfo) {
    return new Promise(resolve => {
      // if (userInfo.roles.includes('admin')) {
      //   accessedRoutes = userInfo.routes || []
      // } else {
      //   accessedRoutes = filterAsyncRoutes(userInfo.routes, userInfo.roles)
      // }
      const accessedRoutes = filterAsyncRoutes(userInfo.routes, userInfo.roles)

      const flatRoutes = generateFlatRoutes(accessedRoutes)
      // console.log(flatRoutes)
      commit('SET_ROUTES', accessedRoutes)
      resolve(flatRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
